package com.aliyun.openservice.iot.as.bridge.demo.core;

import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.aliyun.iot.as.bridge.core.BridgeBootstrap;
import com.aliyun.iot.as.bridge.core.config.ConfigFactory;
import com.aliyun.iot.as.bridge.core.handler.DownlinkChannelHandler;
import com.aliyun.iot.as.bridge.core.handler.tsl.TslUplinkHandler;
import com.aliyun.iot.as.bridge.core.model.DeviceIdentity;
import com.aliyun.iot.as.bridge.core.model.ProtocolMessage;
import com.aliyun.iot.as.bridge.core.model.Session;
import com.aliyun.iot.as.bridge.core.model.tsl.ThingEventTypes;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 演示如何使用TSL（Thing Specification Language）与IoT平台进行交互的示例类
 */
public class BridgeTslDemo {

    // 日志记录器
    private static Logger log = LoggerFactory.getLogger(BridgeTslDemo.class);

    // 网桥引导程序
    private static BridgeBootstrap bridgeBootstrap;

    /**
     * 在IoT平台Web控制台中创建的自定义主题模板
     */
    private final static String TOPIC_TEMPLATE_USER_DEFINE = "/%s/%s/user/update";

    // 属性发布的有效载荷模板
    private final static String PROP_POST_PAYLOAD_TEMPLATE = "Hello IoT Bridge";

    // 创建线程池，用于处理下行消息
    private static ExecutorService executorService  = new ThreadPoolExecutor(
        Runtime.getRuntime().availableProcessors(),
        Runtime.getRuntime().availableProcessors() * 2,
        60, TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(1000),
        new ThreadFactoryBuilder().setDaemon(true).setNameFormat("bridge-downlink-handle-%d").build(),
        new ThreadPoolExecutor.AbortPolicy());

    // 随机数生成器，用于生成模拟数据
    private final static Random random = new Random();

    public static void main(String args[]) {
        // 使用默认的application.conf和devices.conf配置文件
        bridgeBootstrap = new BridgeBootstrap();
        // 启动网桥，并设置下行通道处理器
        bridgeBootstrap.bootstrap(new DownlinkChannelHandler() {
            @Override
            public boolean pushToDevice(Session session, String topic, byte[] payload) {
                // 获取来自云端的下行消息，并提交到线程池处理
                executorService.submit(() -> handleDownLinkMessage(session, topic, payload));
                return true;
            }

            @Override
            public boolean broadcast(String s, byte[] bytes) {
                // 广播功能未实现
                return false;
            }
        });
        log.info("======== Bridge bootstrap success =========");
        
        // 原始设备标识，在devices.conf中定义
        String originalIdentity = "demoDevice1";

        // 特定协议的设备会话，如果没有，可以使用空对象
        Object originalChannel = new Object();
        Session session = Session.newInstance(originalIdentity, originalChannel);
        
        // 设备上线
        TslUplinkHandler tslUplinkHandler = new TslUplinkHandler();
        tslUplinkHandler.doOnline(session, originalIdentity);

        // 上报属性
        // 属性'testProp'在IoT平台Web控制台中定义
        String requestId = String.valueOf(random.nextInt(1000));
        tslUplinkHandler.reportProperty(requestId, originalIdentity, "testProp", random.nextInt(100));

        // 触发事件
        // 事件'testEvent'在IoT平台Web控制台中定义
        requestId = String.valueOf(random.nextInt(1000));
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("testEventParam", 123);
        tslUplinkHandler.fireEvent(originalIdentity, "testEvent", ThingEventTypes.INFO, params);

        // 更新设备标签
        // 标签'testDeviceTag'在IoT平台Web控制台中定义
        requestId = String.valueOf(random.nextInt(1000));
        tslUplinkHandler.updateDeviceTag(requestId, originalIdentity, "testDeviceTag", String.valueOf(random.nextInt(1000)));

        // 发布自定义主题
        // 主题模板 ${TOPIC_TEMPLATE_USER_DEFINE} 在IoT平台Web控制台中定义
        DeviceIdentity deviceIdentity = ConfigFactory.getDeviceConfigManager().getDeviceIdentity(originalIdentity);
        ProtocolMessage protocolMessage = new ProtocolMessage();
        protocolMessage.setPayload(PROP_POST_PAYLOAD_TEMPLATE.getBytes());
        protocolMessage.setQos(0);
        protocolMessage.setTopic(String.format(TOPIC_TEMPLATE_USER_DEFINE, deviceIdentity.getProductKey(), deviceIdentity.getDeviceName()));
        tslUplinkHandler.doPublishAsync(originalIdentity, protocolMessage);
    }

    /**
     * 处理下行消息的方法
     * @param session 会话信息
     * @param topic 消息主题
     * @param payload 消息内容
     */
    private static void handleDownLinkMessage(Session session, String topic, byte[] payload) {
        String content = new String(payload);
        log.info("Get DownLink message, session:{}, topic:{}, content:{}", session, topic, content);
        Object channel = session.getChannel();
        String originalIdentity = session.getOriginalIdentity();
        // 例如，你可以通过channel将消息发送到设备，这取决于你的具体服务器实现
    }
}
